package tcu.yuyp.service.impl;


import tcu.yuyp.pojo.Invitation;
import tcu.yuyp.pojo.R;
import tcu.yuyp.repository.InvitationsRepository;
import tcu.yuyp.service.Utils;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.StreamSupport;

//用于服务InvitationsServlet类
public class InvitationsServiceImpl implements tcu.yuyp.service.InvitationsService {
    InvitationsServiceImpl invitationsServiceImpl;
    //声明InvitationsRepository类的对象
    InvitationsRepository invitationsRepository;
    //通过spring容器为InvitationsRepository类的实例对象赋值的InvitationsService的构造方法

    //构造方法
    public InvitationsServiceImpl(InvitationsRepository invitationsRepository) {
        this.invitationsRepository = invitationsRepository;
    }


    //判断客户端的请求，并执行对应的方法--对应servlet中的doPost方法
    public void postInvitationResponse(Invitation newInvitation, String requestURI, R r, String loginName) {
        invitationsServiceImpl = new InvitationsServiceImpl(invitationsRepository);


        if (Utils.getNumberOfURI(requestURI).get("getNumberOfURI") == 2) {
            //发布邀请函的请求
            invitationsServiceImpl.postInvitation(newInvitation, loginName, r);
            return;
        }

        //调用repository层的方法获取邀请函的集合
        List<Invitation> invitationList = invitationsServiceImpl.turnForInvitationList(invitationsRepository.findAll());

        //报名参加邀请函的请求
        invitationsServiceImpl.postJoinInvitation(invitationList, requestURI, r, loginName);

    }

    //报名参加邀请函的方法
    public void postJoinInvitation(List<Invitation> invitationList, String requestURI, R r, String loginName) {
        invitationsServiceImpl = new InvitationsServiceImpl(invitationsRepository);

        for (var invitation : invitationList) {
            //获取访问中携带的想要加入的邀请函的id与邀请函集合中的邀请函id进行比对
            if (invitation.getId().equals(Utils.getNumberOfURI(requestURI).get("id"))) {
                //邀请函列表中含有对应id的邀请函

                //查验邀请函是否已经过期
                if (invitationsServiceImpl.isExpire(invitation)) {
                    //邀请函过期
                    r.setCode(400);
                    r.setMsg("报名失败：报名已经截止");
                    return;
                }
                //查验邀请函人数是否已经满员
                if (invitationsServiceImpl.isFull(invitation)) {
                    //满员
                    r.setCode(400);
                    r.setMsg("报名失败：报名人数已满");
                    return;
                }
                //查验邀请函是否为自己所创建
                if (invitationsServiceImpl.isFoundedByHimself(invitation, loginName)) {
                    //是自己所创建
                    r.setCode(400);
                    r.setMsg("报名失败：不能报名自己创建的邀请函");
                    return;
                }
                //查验报名人员是否重复
                if (invitationsServiceImpl.isNameRepeat(invitation, loginName)) {
                    //重复
                    r.setCode(400);
                    r.setMsg("报名失败，用户名已存在");
                    return;
                }
                //成功报名的情况-->改变邀请函的信息
                invitationsServiceImpl.succeedJoinInvitation(invitation, loginName);
                r.setCode(200);
                r.setData("ok");
                return;
            }
        }
        //邀请函集合中不存在指定id的邀请函
        r.setCode(400);
        r.setMsg("报名失败，不存在该邀请函");
    }

    //成功报名的方法--> 先更新邀请函信息：已报名的人数 和 包含已报名的用户的用户名数组-->然后更新数据库中的邀请函的表
    public void succeedJoinInvitation(Invitation invitation, String loginName) {
        //1.更新邀请函已报名的人员数量
        //先判断医保名人员是否为空
        if (invitation.getRegistered() == null){
            //为空，直接设置已报名人数为0
            invitation.setRegistered(0);
        }
        //更新邀请函已报名人员的数量
        invitation.setRegistered(invitation.getRegistered() + 1);


        //2.更新invitation原来的已经报名的用户名数组
        //获取原来的邀请函的已报名的用户的用户名数组
        String[] namesOfInvitation = invitation.getNamesOfInvitation();


        //判断原来的已报名的用户的用户名数组是否为空
        if (namesOfInvitation == null) {
            //数组为空-->不需要通过循环原来的数据实现更新数据
            //创建新数组-->长度为1,并直接将数据添加到新的数组中
            String[] newNamesOfInvitation = {loginName};
            //更新邀请函的数组
            invitation.setNamesOfInvitation(newNamesOfInvitation);

            return;
        }
        //原来的邀请函已报名的用户的用户名数组不为空的情况
        //创建新的数组
        String[] newNamesOfInvitation = new String[namesOfInvitation.length + 1];
        //更新参加该邀请函的用户的用户名数组
        for (int i = 0; i < newNamesOfInvitation.length; i++) {
            //更新最新报名的用户的用户名
            if (i == newNamesOfInvitation.length - 1) {
                newNamesOfInvitation[i] = loginName;
                break;//结束循环
            }
            //替换数据
            newNamesOfInvitation[i] = namesOfInvitation[i];
        }
        //更新邀请函中的数组数据
        invitation.setNamesOfInvitation(newNamesOfInvitation);


        //最后更新数据库的邀请函表中的对应的邀请函
        invitationsRepository.save(invitation);
    }


    //查验邀请函报名人员是否重复的方法
    public boolean isNameRepeat(Invitation invitation, String loginName) {
        //获取指定邀请函的报名人员名字集合
        String[] namesOfInvitation = invitation.getNamesOfInvitation();

        //判断数组是否为空
        if (namesOfInvitation == null) {
            return false;
        }

        //数组不为空，查看数组中是否含有相同的用户名
        for (String s : namesOfInvitation) {
            if (loginName.equals(s)) {
                //重复
                return true;
            }
            //不重复
        }
        return false;
    }


    //查验该邀请函是否为自己所创建的方法
    public boolean isFoundedByHimself(Invitation invitation, String loginName) {
        String founder = invitation.getUser();//获取邀请函的创建人

        //是自己所创建
        return loginName.equals(founder);
        //不是自己创建
    }


    //查验邀请函人数是否已经满员的方法
    public boolean isFull(Invitation invitation) {
        invitationsServiceImpl = new InvitationsServiceImpl(invitationsRepository);

        //报名占比率达到100%-->报名人员已经满员
        return invitationsServiceImpl.countPercent(invitation).equals("100%");
    }


    //查验邀请函是否过期的方法
    public boolean isExpire(Invitation invitation) {
        //获取邀请函的起止日期
        LocalDate deadline = invitation.getDeadline();
        LocalDate now = LocalDate.now();

        //早于邀请函报名截止时间-->未过期-->false
        //邀请函已经截至-->已经过期-->true
        return !now.isBefore(deadline);
    }


    //发布邀请函的方法-->将需要发布的邀请函直接加入到数据库对应的邀请函表中
    public void postInvitation(Invitation newInvitation, String loginName, R r) {

        //设置发布邀请函的人员的名字
        newInvitation.setUser(loginName);
        //将邀请函直接添加到邀请函数据库表中
        invitationsRepository.save(newInvitation);

        r.setCode(200);
        r.setData("ok");
    }


    //查看邀请函的方法-->对应servlet中的doGet方法
    public void getInvitationResponse(R r, String requestURI) {
        invitationsServiceImpl = new InvitationsServiceImpl(invitationsRepository);

        //调用repository层的方法获取邀请函的迭代器对象，并且将其转化为集合对象
        List<Invitation> invitationList = invitationsServiceImpl.turnForInvitationList(invitationsRepository.findAll());


        //创建指定集合，输出指定的Invitation列表数据
        List<Invitation> invitationListForList = new ArrayList<>();


        if (Utils.getNumberOfURI(requestURI).get("getNumberOfURI") == 2) {
            //存在2个"/”,就是查看邀请函列表

            //执行对应的查看邀请函列表的方法
            invitationsServiceImpl.getInvitationList(invitationListForList, invitationList);//直接更改invitationListForList集合的值

            //设置响应状态码
            r.setCode(200);
            if (invitationListForList.isEmpty()) {
                //邀请函列表为空
                r.setMsg("邀请函列表为空");
                return;
            }
            //邀请函列表不为空
            r.setData(invitationListForList);//调用方法，返回指定的数据
            return;
        }
        if (Utils.getNumberOfURI(requestURI).get("getNumberOfURI") == 3) {
            //存在3个"/”,就是查看具体id对应的邀请函的详情信息

            for (Invitation invitation : invitationList) {
                if (Utils.getNumberOfURI(requestURI).get("id").equals(invitation.getId())) {
                    //存在对应id的邀请函-->产看邀请函详情
                    r.setCode(200);
                    r.setData(invitationsServiceImpl.getInvitationDetail(invitation));
                    return;
                }
            }
            //不存在对应id的邀请函
            r.setCode(400);
            r.setMsg("查询失败，不存在对应id的邀请函信息");
        }
    }


    //返回查看邀请函详情指定数据的方法
    public Invitation getInvitationDetail(Invitation invitation) {
        //ID，标题，简介，起始日期，终止日期，创建人，邀请人数，已报名人数，报名截止日期
        Invitation detailOfInvitation = new Invitation();

        detailOfInvitation.setId(invitation.getId());
        detailOfInvitation.setTitle(invitation.getTitle());
        detailOfInvitation.setDescription(invitation.getDescription());
        detailOfInvitation.setStartDate(invitation.getStartDate());
        detailOfInvitation.setEndDate(invitation.getEndDate());
        detailOfInvitation.setUser(invitation.getUser());
        detailOfInvitation.setNumber(invitation.getNumber());
        detailOfInvitation.setRegistered(invitation.getRegistered());
        detailOfInvitation.setDeadline(invitation.getDeadline());

        return detailOfInvitation;
    }


    //返回查看邀请函列表指定数据的方法
    public void getInvitationList(List<Invitation> invitationListForList, List<Invitation> invitationList) {
        invitationsServiceImpl = new InvitationsServiceImpl(invitationsRepository);

        //邀请函id，标题，发布日期，报名率

        //判断是否为空
        if (invitationList == null) {
            //如果为空，直接接将自己返回过去
            return;
        }
        for (var invitation : invitationList) {
            //判断是邀请函是否过期
            if (invitationsServiceImpl.isExpire(invitation)) {
                //过期-->结束本次循环
                continue;
            }
            //判断邀请函是否已经满员
            if (invitationsServiceImpl.isFull(invitation)) {
                //满员-->结束本次循环
                continue;
            }

            //符合未过期且人员未满的邀请函
            //将邀请函中的数据放到指定实体类的集合中
            Invitation invitationForList = invitationsServiceImpl.getInvitationForList(invitation);
            //将符合条件的邀请函放到返回查看邀请函列表的集合中
            invitationListForList.add(invitationForList);
        }
    }

    //获取 查看邀请函列表指定信息 的方法
    public Invitation getInvitationForList(Invitation invitation) {
        invitationsServiceImpl = new InvitationsServiceImpl(invitationsRepository);

        Invitation newInvitation = new Invitation();

        newInvitation.setId(invitation.getId());
        newInvitation.setTitle(invitation.getTitle());
        newInvitation.setStartDate(invitation.getStartDate());
        newInvitation.setUser(invitation.getUser());
        //计算报名人数占比率

        newInvitation.setPercent(invitationsServiceImpl.countPercent(invitation));

        return newInvitation;
    }

    //计算邀请函报名人数比例
    public String countPercent(Invitation invitation) {
        //注意：invitation实体类中所有的数字类型都是Integer类型（属于对象，而不是基本数据类型），因此使用前需要先判断是否为空
        int number;//邀请函人数
        int registered;//已有人数
        if (invitation.getNumber() == null) {
            number = 0;
        } else {
            number = invitation.getNumber();
        }
        if (invitation.getNamesOfInvitation() == null) {
            registered = 0;
        } else {
            registered = invitation.getRegistered();
        }
        return ((registered * 100) / number) + "%";
    }

    //将迭代器对象转化为List集合对象
    public List<Invitation> turnForInvitationList(Iterable<Invitation> invitationIterable) {

        return StreamSupport.stream(invitationIterable.spliterator(), false)
                .toList();
    }

}
